//
//  ADCollectionViewController.m
//  ADKit
//
//  Created by duzexu on 2018/4/4.
//

#import "ADCollectionViewController.h"
#import "ADKitHeaders.h"

@interface ADCollectionViewController () {
    BOOL emptyDataSetInit;
}

@property (nonatomic, readwrite, weak)  UICollectionView *collectionView;
@property (nonatomic, readonly, strong) ADCollectionViewModel *viewModel;

@end

@implementation ADCollectionViewController
@dynamic viewModel;

- (void)dealloc {
    _collectionView.dataSource = nil;
    _collectionView.delegate = nil;
}

/// override
- (void)initialize {
    [super initialize];
    [self ad__setupSubViews];
    if (self.viewModel.shouldFetchLocalDataOnViewModelInitialize) {
        [self.viewModel.requestLocalDataCommand execute:nil];
    }
    if ([self.viewModel shouldRequestRemoteDataOnViewDidLoad] && !self.viewModel.shouldPullDownToRefresh) {
        [self.viewModel.requestRemoteDataCommand execute:@1];
    }
}

- (void)bindViewModel {
    [super bindViewModel];
    @weakify(self);
    /// 隐藏emptyView
    [self.viewModel.requestRemoteDataCommand.executing subscribeNext:^(NSNumber *executing) {
        @strongify(self)
        UIView *emptyDataSetView = [self.collectionView.subviews.rac_sequence objectPassingTest:^(UIView *view) {
            return [NSStringFromClass(view.class) isEqualToString:@"DZNEmptyDataSetView"];
        }];
        emptyDataSetView.alpha = 1.0 - executing.floatValue;
    }];
    
    [self.viewModel.requestRemoteDataCommand.executionSignals.switchToLatest subscribeNext:^(id _) {
        @strongify(self);
        self.viewModel.networkReachable = YES;
    }];
    
    [self.viewModel.requestRemoteDataCommand.errors subscribeNext:^(id _) {
        @strongify(self);
        self.viewModel.networkReachable = self.viewModel.services.reachabilityManager.reachable;
    }];
    
    [[self.viewModel.reloadIndexPaths deliverOnMainThread] subscribeNext:^(id x) {
        @strongify(self);
        if ([x isKindOfClass:[NSArray class]]) {
            [self.collectionView reloadItemsAtIndexPaths:x];
        }else if ([x isKindOfClass:[NSIndexPath class]]) {
            [self.collectionView reloadItemsAtIndexPaths:@[x]];
        }else{
            [self reloadData];
        }
    }];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    UIView *emptyDataSetView = [self.collectionView.subviews.rac_sequence objectPassingTest:^(UIView *view) {
        return [NSStringFromClass(view.class) isEqualToString:@"DZNEmptyDataSetView"];
    }];
    if (emptyDataSetView && !emptyDataSetInit) {
        emptyDataSetInit=YES;
        emptyDataSetView.alpha = 0;
    }
}

#pragma mark - 设置子控件
- (void)ad__setupSubViews {
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:self.viewModel.collectionViewLayout];
    collectionView.backgroundColor = self.view.backgroundColor;
    collectionView.contentInset  = self.viewModel.contentInset;
    // set delegate and dataSource
    collectionView.delegate = self.viewModel;
    collectionView.dataSource = self.viewModel;
    [self.view addSubview:collectionView];
    [collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view).insets(self.viewModel.collectionViewInset);
    }];
    
    /// 占位
    collectionView.emptyDataSetDelegate = self.viewModel;
    collectionView.emptyDataSetSource = self.viewModel;
    
    if (@available(iOS 11.0, *)) {
        collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    if (@available(iOS 7.0, *)) {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }
    
    self.collectionView = collectionView;
    
    // 注册cell
    [self.viewModel registCollectionViewCell:collectionView];
    
    /// 添加加载和刷新控件
    if (self.viewModel.shouldPullDownToRefresh) {
        @weakify(self);
        Class cls = self.viewModel.refreshHeaderClass;
        MJRefreshHeader *header;
        if (cls) {
            header = [cls headerWithRefreshingBlock:^{
                @strongify(self);
                [self collectionViewDidTriggerHeaderRefresh];
            }];
        }else{
            header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
                @strongify(self);
                [self collectionViewDidTriggerHeaderRefresh];
            }];
        }
        self.collectionView.mj_header = header;
        [self.collectionView.mj_header beginRefreshing];
    }
    
    if (self.viewModel.shouldPullUpToLoadMore) {
        @weakify(self);
        Class cls = self.viewModel.refreshFooterClass;
        MJRefreshFooter *footer;
        if (cls) {
            footer = [cls footerWithRefreshingBlock:^{
                @strongify(self);
                [self collectionDidTriggerFooterRefresh];
            }];
        }else{
            footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
                @strongify(self);
                [self collectionDidTriggerFooterRefresh];
            }];
        }
        footer.hidden = YES;
        self.collectionView.mj_footer = footer;
        /// 隐藏footer or 无更多数据
        RAC(self.collectionView.mj_footer, hidden) = [[RACObserve(self.viewModel, noMoreData)
                                                  deliverOnMainThread] map:^id(id value) {
            @strongify(self)
            if (self.viewModel.shouldEndRefreshingWithNoMoreData) return @(0);
            return [value boolValue] ? @(1) : @(0);
        }];
    }
}

#pragma mark - 上下拉刷新事件
- (void)collectionViewDidTriggerHeaderRefresh {
    @weakify(self)
    [[[self.viewModel.requestRemoteDataCommand
       execute:@1]
      deliverOnMainThread]
     subscribeNext:^(id x) {
         @strongify(self)
         self.viewModel.page = 1;
         if (self.viewModel.shouldEndRefreshingWithNoMoreData) {
             [self.collectionView.mj_footer resetNoMoreData];
         }
     } error:^(NSError *error) {
         @strongify(self)
         [self.collectionView.mj_header endRefreshing];
     } completed:^{
         @strongify(self)
         [self.collectionView.mj_header endRefreshing];
         [self _requestDataCompleted];
     }];
}

- (void)collectionDidTriggerFooterRefresh {
    @weakify(self);
    [[[self.viewModel.requestRemoteDataCommand
       execute:@(self.viewModel.page + 1)]
      deliverOnMainThread]
     subscribeNext:^(id x) {
         @strongify(self)
         self.viewModel.page += 1;
     } error:^(NSError *error) {
         @strongify(self);
         [self.collectionView.mj_footer endRefreshing];
     } completed:^{
         @strongify(self)
         [self.collectionView.mj_footer endRefreshing];
         [self _requestDataCompleted];
     }];
}

#pragma mark - sub class can override it
- (void)reloadData {
    [self.collectionView reloadData];
}

#pragma mark - 辅助方法
- (void)_requestDataCompleted {
    if (self.viewModel.shouldEndRefreshingWithNoMoreData && self.viewModel.noMoreData) {
        [self.collectionView.mj_footer endRefreshingWithNoMoreData];
    }
    if (self.viewModel.noMoreData && self.viewModel.dataSource.count == 0) {
        self.collectionView.mj_footer.hidden = YES;
    }
    [self.viewModel requestDataCompleted];
}

@end
